﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AnalizadorCsv.Clases;
using System.Xml.Serialization;
using System.Xml;
using System.IO;

namespace AnalizadorCsv.Analizador
{
    public class ComponenteAnalizador
    {
        protected Campos campos;
        protected String archivoXml;
        protected String archivoCsv;
        protected DefaultCsv contenidoCsv;
        protected String archivoError;
        protected Detalles detalles;
        protected int contErrores;
        public ComponenteAnalizador(String archivoXml, String archivoCsv, Detalles detalles, int contErrores)
        {
            this.archivoXml = archivoXml;
            this.archivoCsv = archivoCsv;
            this.detalles = detalles;
            FileInfo fi = new FileInfo(archivoCsv);
            System.IO.Directory.CreateDirectory(fi.Directory + "\\Resultado");
            this.archivoError = fi.Directory + "\\Resultado\\" + fi.Name + DateTime.Now.ToString("dd_MM_yyyy__HH_mm_ss") +"_error.txt";
            this.contErrores = contErrores;
            this.contenidoCsv = new DefaultCsv(archivoCsv, this.archivoError);
        }
        public virtual void ejecutarAnalisis()
        {
            obtenerCampos();
            extraerArchivo();
            analizarCondicionesBasicas();
            acomodarFormatos();
            analizarRestriccionesEspeciales();
            generarNuevoArchivo();
        }
        public virtual void obtenerCampos()
        {
            Console.WriteLine("---Obteniendo Campos---");
            this.detalles.actualizarProceso("Obteniendo Campos");
            XmlSerializer serial = new XmlSerializer(typeof(Campos));
            XmlTextReader xt = new XmlTextReader(this.archivoXml);
            campos = (Campos)serial.Deserialize(xt);
            xt.Close();

        }
        public virtual void analizarRestriccionesEspeciales()
        {
            Console.WriteLine("---Analizando Restricciones Especiales---");
            this.detalles.actualizarProceso("Analizando Restricciones Especiales");
        }
        public virtual void generarNuevoArchivo()
        {
            Console.WriteLine("---Generando Nuevo Archivo---");
            this.detalles.actualizarProceso("Generando nuevo archivo");
            this.contenidoCsv.guardarArchivo();
        }
        public virtual void analizarCondicionesBasicas()
        {
            Console.WriteLine("---Analizando condiciones Basicas---");
            this.detalles.actualizarProceso("Analizando Condiciones Basicas");
            List<CamposConfiguracion> camconf = campos.campoDetalle.ToList();
            foreach (CamposConfiguracion c in camconf)
            {
                Console.WriteLine("Analizando "+c.nombreCampo);
                if (c.noBlank)
                {
                    if (contenidoCsv.existeColumna(c.nombreCampo))
                    {
                        if (c.reemplazar)
                        {
                            if (!contenidoCsv.verificarVacios(c.nombreCampo, c.textoReemplazo))
                            {
                                generarLogError("No se pudo reemplazar data en filas vacias de la columna " + c.nombreCampo);
                            }
                        }
                        else
                        {
                            if (!contenidoCsv.verificarVacios(c.nombreCampo))
                            {
                                generarLogError("Existen Campos Vacios en la columna " + c.nombreCampo);
                            }
                        }
                    }
                    else
                    {
                        generarLogError("No existe la columna "+c.nombreCampo);
                    }
                }
            }
        }
        public virtual void acomodarFormatos()
        {
            Console.WriteLine("---Acomodando Formatos---");
            this.detalles.actualizarProceso("Acomodando Formatos");
            List<CamposConfiguracion> camconf = campos.campoDetalle.ToList();
            foreach (CamposConfiguracion c in camconf)
            {
                if (c.tipo == "Texto")
                {
                }
                else
                {
                    if (c.tipo == "ZipCode")
                    {
                        if (!contenidoCsv.acomodarporZipCode(c.nombreCampo))
                        {
                            generarLogError("Problema al llevar al formato correcto de zipcode en el campo " + c.nombreCampo);
                        }
                    }
                    else
                    {
                        if (c.tipo == "Fecha")
                        {
                            if (!contenidoCsv.acomodarporFecha(c.nombreCampo))
                            {
                                generarLogError("Problema al llevar al formato correcto de Fecha en el campo " + c.nombreCampo);
                            }
                        }
                        else
                        {
                            if (c.tipo == "Fecha-Hora")
                            {
                                if (!contenidoCsv.acomodarporFechaHora(c.nombreCampo))
                                {
                                    generarLogError("Problema al llevar al formato correcto de Fecha-Hora en el campo " + c.nombreCampo);
                                }
                            }
                        }
                    }
                }
            }
        }
        public virtual void extraerArchivo()
        {
            Console.WriteLine("---Obteniendo Archivo---");
            this.detalles.actualizarProceso("Obteniendo Archivo");
            this.contenidoCsv.abrirArchivo();
        }
        public void generarLogError(String error)
        {
            contErrores++;
            this.detalles.asignarErrores(contErrores);
            /*StreamWriter sw = new StreamWriter(this.archivoError, true, Encoding.Default);
            sw.WriteLine("(" + DateTime.Now.ToString() + ") - " + error);
            sw.Close();*/
        }
        public int totalErrores()
        {
            return contErrores;
        }
    }
}
